GestLab is a major improvement to Gestalt.Appl, two JP Curcio’s freeware tools dedicated to the Mac OS Gestalt Manager. Latest English and French versions of these two apps can be found at http://www.rgaros.nl/gestalt/index.html#appl.
You'll find in this doc the following points:
• Requirements
• Search info and dynamic database
• Main window = local configuration
• Database window
• Info window
• Virtual configs
• Compare two configs
• Pseudo-selectors
• Secure launching (if you got a System error when launching GestLab)
• Help balloons
• To-do list (if enough time to implement)
• Known bugs
• Histo
Please, if your configuration displays selectors that are not in the GestLab database, save this config (Command-S) and send the resulting file at jpc83@calva.net. The new selectors can then be added to the database and will be available in the next release of GestLab.
Thanks for you collaboration!
Note that because a GestLab config file can contain non-ASCII characters, you have to binhex the file before sending it via Internet. To binhex a file and compact it, you can use a well-configured version of Aladdin’s DropStuff utility.
Requirements
GestLab needs Appearance Manager 1.0.1 (as found in Mac OS 8.1). If not present, you can only save your configuration and see it on another machine where GestLab works. Continue to use Gestalt.Appl on Systems before 8.1, or try to install Appearance Manager (beginning with Mac OS 7.1) to use GestLab. Appearance Manager is available at Apple’s Internet site. Navigation Services are implemented under Mac OS 8.5 only.
Search info and dynamic database
When launched, GestLab searches info on selectors present in config but not present in its database (the “static database” presently stored in its resource fork). If the selector name does not correspond to a file signature, GestLab looks inside most of files in System Folder, Extensions folder and Control Panels folder for strings in data fork and resource fork that are the same as selector name. This process can be very long and it is not perfectly accurate. But when only one file is found for a selector, probability it is this file that posted the selector is strong (see later). Sorry, this process is not implemented as a thread, so you cannot use GestLab during its progress, but you can interrupt it by pressing space bar or switch to another application and let it continue in background.
“Search Info” is also a command that can be called from the “Data” menu when the local config window is frontmost, but it is restricted to one selector at a time (this command searches info in the same list of files). A more targeted search can be launched with the “Search Info In Folder…” command. If Navigation Services are supported, it searches info in every file found in the chosen folder (and every folder nested in this folder). If Navigation Services are not present, this folder is by default the active System Folder.
All info found is stored in the “base+” file in the same folder as GestLab (called the “dynamic database” or the “unknown selectors database”). The next time you launch it, GestLab looks for info in this file and searches only for selectors not present in it. When you save your configuration, an optimized copy of the dynamic database is included in the document.
When you call “Search Info” or “Search Info In Folder…” command, info found about a selector during search is added to precedent info about this selector in the dynamic database, even if it is already present. Info about one selector in dynamic database can be deleted by using “Delete Info” command from the “Data” menu (this applies only on the local config).
Info in dynamic database concerns potential candidates that can have posted an unknown selector. It can be:
• a signature: only the first file whose signature is equal to the selector code is stored, but many files can have it, so this info is not 100% accurate (use “Search Info” command to get more info);
• a data fork: string was found in the file data fork, but it is not necessary because of the Gestalt selector;
• a resource fork: a first global check found string in the resource fork file, a second check looks for the string within each individual resource. For each resource where string was found, GestLab also checks for presence of functions NewGestalt, ReplaceGestalt, NewGestaltValue, ReplaceGestaltValue or SetGestaltValue. So if you see a file that contains an ‘INIT’ resource (or any resource with executable code in it) with NewGestaltValue and the selector code simultaneously, probability is very strong that it is a good candidate! The same in a ‘PICT’ resource is certainly a coincidence;
• a driver: GestLab searches at launching for the string in 16 kilobytes from the beginning of each driver loaded in memory. Take this info only as an indication: there is no guarantee the string belongs to the driver if it is found (a more precise analysis is needed with tools like MacsBug). A driver search can be launched by using the hidden Command-Control-J command.
Note: there is no reason for the “base+” file to become too fat. If you find new info and send your configuration to me, the next version of GestLab will include it and you can then delete this info from the dynamic database (or even the “base+” file itself).
When the string cannot be found in any targeted files or in drivers, the only info stored on the unknown selector is the result type: a Mac OS pointer, a Mac OS handle or an unknown type. Why is it impossible to determine the origin of some selectors ? Because code can reside in a compressed resource, code is sometimes splitted by the compiler, code can be constructed on the fly, etc. In that cases, the best way is to play with extensions: reboot the machine with and without an extension to see if the unknown Gestalt selector is posted or not. The dynamic database is not aware of these manipulations.
Main window = local configuration
The first window GestLab opens is the local configuration. 6 choices to the selector list on the left (the main list):
• Pure Gestalt config: All the selectors known by the Gestalt Manager when GestLab was launched. If a selector is not in the static database, it appears in red. If it returns an error, it appears in italics.
• Extended config with pseudos: The same list, with pseudo-selectors posted by GestLab added (they appear in blue).
• Informative selectors: A list including only selectors that do not carry hexadecimal info.
• New or unknown info: it lists all the selectors not present in the static database, some selectors present in the database but whose origin is unknown (thanks if you have an idea about them!), and all the selectors that contain a new info compared to the info present in the static database (a new attribute, a new value in a list or a new version number). New or unknown info always is displayed or interpreted in red. The more the database will be exhaustive and updated, the less items will be in this list!
• Selectors with error: All the selectors that return an error in the config (including selectors with side effect whose value is not yet known).
• Dynamic database: A list that reflects the contents of the “base+” file for the local configuration, or the dynamic database for a saved configuration.
On the right is the interpretation of the selector selected in the main list. If a second list appears in this part, one or more of these items can be selected. Particular comments are then available in the info pane. When no item is selected, general comments come back.
Lists in GestLab are more present than in Gestalt.Appl. GestLab also tries to find if some values returned are Mac OS pointers or handles, and displays memory accordingly in a new hexa box. When an unknown value type could be an address, hexa box is displayed with first 10 KB of data beginning at this address (memory dump).
The window is resizable. When size is not minimal, the panes within the window can be resized too, thanks to the two separator controls (but only the horizontal separator is really useful). Position and size of this window and its panes are stored in the GestLab Prefs file (created in the same folder as GestLab, but that can be move in the Preferences folder if you want).
Values for all selectors in the local configuration (except those known to present side effects when called) are computed only once when GestLab is starting. If you think that a selector value has changed (or if you want to know the value of a selector with side effects), select its code and use the “Get Value” command in the “Data” menu. You can also update the whole configuration by calling the “Update Config” command in the same menu. If Compare windows are linked to the local config, they are updated too.
Database window
Based on the same model as main window, it displays data from the static database. The exhaustive list of selectors can be sorted by code (alphabetic order) or by date (that can be used to look for the more recent selectors added to the base). You can also display a limited list based on any combination of selector types or selector flags.
The value associated with a selector is used to find new info. When this value is null, either no compare succeeds (case of single values like a version number) or a search algorithm is used (case of value to be found in a list).
“Find…” and “Fing Again” commands allow to search for an exact character string in the static database (no joker character), when its window is the frontmost window. You can start a “Find…” either on the first selector or on the selected one, and the search loops on all the displayed selectors in the list. “Fing Again” always starts on the selected selector. Press any key to cancel a running “Find” command.
Preferences on the database window are stored independantly of main window. They remember its position and if the window was visible or not the last time GestLab was quitted.
Info window
Its main goal is to display and edit an internal title and comments associated with virtual configs. This info is not kept for the local configuration if the config is not saved. This info is automatically saved on other configurations.
The internal title is a 63-character string associated with any single config. It can be different from the window title (which is the same as file stored on disk). It is used to identify a config in a Compare window, and will be used more intensively in a future version.
Comments are free but limited to 255 characters. They can be associated with any single config or composite document (ie only Compare configs for now).
If the frontmost document is open from a file, other fields tell the file path, the version of the application that saved this document and when. For a Compare, both window titles (instead of internal titles) are also displayed. Note: the popup menu that displays the file path becomes active if an utility like Turlough O’Connor’s FinderPop is present on the machine.
Despite of its appearance, it is not a floating window (should it have the look of a standard window?). Info is given about the frontmost window that is not the info window. GestLab remembers visibility and position for this window and adjusts its size automatically.
Virtual configs
Any single configuration can be exported as text to feed an external database or to be printed by SimpleText. The local configuration can be saved as a virtual configuration to be reopened later.
In this version, a virtual config stores:
• single values returned by a selector;
• data linked with pseudo-selectors (list of extensions, control panels and drivers are stored for a better analysis of the config);
• data from structured selectors;
• the first 24 bytes found at the address returned by some selectors (pointers, handles, etc., everywhere GestLab is displaying an hexa box);
• info displayed in the Info window;
• a part of the dynamic database limited to the selectors present in the local configuration at a time it is saved.
The saving action can seem long. It is because the version number of all extensions and control panels is read from disk and stored in the virtual configuration.
So a live local configuration still gives more info than the associated virtual config wherever hexa boxes are available, but a virtual config stores enough data to allow remote analysis without becoming too big (a virtual config file is usually less than 16 KB, except if you have tons of extensions in your System Folder).
Virtual configs created using GestLab cannot be opened by Gestalt.Appl, but all configs created using Gestalt.Appl can be opened by GestLab.
When opened, a virtual config window inherits the settings of the main window. No preferences are stored for a virtual config.
Compare two configs
When one or more virtual configs are opened, the command “Compare” in the “File” menu is activated. The configs in the two frontmost windows are compared (other compare, database and info windows are ignored), and a new window is displayed to explicitly show differences between both configs.
Checkboxes allow to restrict the list of selectors. Levels are:
• Level 0: selectors returns exactly the same value;
• Level 1: value returned is not the same, but the difference is not important (when the value is a memory address, for example);
• Level 2: value returned is not the same, but we don't know if the difference is important (applies on unknown selectors);
• Level 3: value returned is not the same, and the difference is seen as important (when the value is a list of attributes, for example);
• Level 4: a same selector presents different flags in two configs (should only occur when a selector is alternatively posted either by NewGestalt or by NewGestaltValue, for example ‘vm ’ virtual memory selector);
• Level 5: a same selector returns a correct value in one config and an error in the other;
• Level 6: the selector is present only in one config.
In GestLab, four pseudo-selectors are designed to list collections of files: ‘Cdvƒ’, ‘Extƒ’, ‘Sysƒ’ and ‘Prœ#’ (see next section). If you double-click one of these pseudo-selectors in a Compare window (they have a blue background), you get a sub-window to explicitly show differences between file lists from both configs (sub-windows are automatically closed when Compare window is closed).
Here again, checkboxes allow to restrict the list of files. Levels are:
• Level 0: files are the same: same name, same version number, same Finder type, same Finder signature;
• Level 1: files have same version number, same Finder type, same Finder signature, but name is different (this happens mainly when you compare configs built from foreign systems, a US config versus a French config, for example). This level applies only when the type-signature pair is unique within the file list;
• Level 2: files have same name, same Finder type, same Finder signature, but a version number is unknown;
• Level 3: files have same name, same Finder type, same Finder signature, but both version numbers are known and they are different;
• Level 4: the file is present only in one config. Note that if the file-signature pair is not unique, files whose names are different are considered absent from other config (background is yellow when pair is unique, magenta if not unique).
Compare extension files, control panels and active processes is a mean to better determine origin of an unknown selector.
If you want to know the impact of an extension on the Gestalt table, save your config, restart without this extension and compare the saved config with the new local config! Idem to test impacts from a new system version.
Note: A “live” Compare window (ie a Compare window not open from a file, but from the “Compare” command) is always the child of two other windows. As soon as you close one of the two parent windows, the associated Compare window is automatically closed (without asking for a Save).
The contents of the Compare window can be saved (the file contains an image of both configs). When you reopen it, you have not a “live” Compare window, but a “static” Compare window that is the child of no window, but potentially the mother of two window configs. If you click the buttons that display the internal title of the two single configs stored in the Compare config, windows displaying these single configs are made visible and active. You can then save them as independant single configurations if you want.
When you select a selector code in a Compare window, the code is selected also in windows linked to it, if available. Interesting with a big screen, because this allows a synchro display of both configs.
You can open or calculate more than one Compare window at the same time.
The “Export as text” command is available to allow printing by SimpleText. No preferences are stored for Compare windows.
Pseudo-selectors
Pseudo-selectors looks like Gestalt selectors, but are not. They are provided by GestLab for more info or internal use.
• ‘Frq2’ calculates processor frequency based on an algorithm different from Apple's ‘pclk’. If results are different, both are displayed. It uses the ‘Prc#’ pseudo-selector that counts the number of active processors.
• ‘Sndv’ returns the Sound Manager version.
• ‘Cdvƒ’ lists the contents of the Control Panel folder at a time when the selector is displayed (only files). This list is used by the command “Search info”. Note that the contents of this folder could have been changed between startup time, GestLab launching time and now. If you select an item in the list, its version is displayed (the contents of both ‘vers’ resources from the local config, only the version number from virtual configs).
• ‘Extƒ’ lists the contents of the Extensions folder at a time when the selector is displayed (excepted for some files like Apple guides). Same notes as ‘Cdvƒ’.
• ‘Sysƒ’ lists the contents of the System Folder at a time when the selector is displayed (excepted for some files like Apple guides). Same notes as ‘Cdvƒ’.
• ‘Prœ#’ lists all the active processes at a time when the selector is displayed. This list is only used for the signature search.
• ‘Drv#’ lists all the active drivers at a time when the selector is displayed. Experimented users can use addresses displayed in this list to search for an unknown selector within MacsBug by disassembling from this address. Other users can try Command-Control-J to search into the first 16 KB of each driver for a string that contains the selected Gestalt code, but even if this string is found, you cannot be sure you still are into this driver nor it reflects a selector posted by NewGestalt or NewGestaltValue!
• ‘Tabl’ lists all the posted Gestalt selectors with their origin (NewGestalt or NewGestaltValue functions). It reflects the real Gestalt table. You can double-click an item in it to select the corresponding code in the main list.
• ‘$00000001’ displays a quick overview of the configuration. Its code was chosen to be the first in the main list, so when you open any single config, this info is displayed.
Secure launching
When GestLab is launched, it looks for every selector present in the system configuration. Some selectors are posted “by value” (using the NewGestaltValue function), others (posted by the NewGestalt function) point on a Gestalt DEFinition procedure, and this GDEF procedure is implicitely called by GestLab, excepted when a given flag (named “Side effect” flag) associated with a given selector in the database is set (for example, ‘VrkS’ selector from Virex anti-virus).
Sometimes GDEF procedures are bugged, and calling them results in a crash when launching GestLab. If this happens, you can think that is the GestLab fault, but it’s not. Try relaunching GestLab by pressing Shift key as soon as possible: GestLab no longer calls any GDEF procedure. Side effect: GestLab cannot display the value returned by selectors posted using NewGestalt function (a -2 error is displayed instead), and you have to call the “Get Value” command on each concerned selector if you want to know it (the “Update Config” command is disabled in this case).
Secure launching is interesting only to determine which GDEF is buggy (you’ll crash when calling “Get Value” on the bad selector). Saving the config after a secure launching is not very useful because the value returned by many selectors is not known.
If the mechanism used by the ‘Tabl’ pseudo-selector cannot be run (because it uses non-documented by Apple features), secure launching cannot be used and GestLab uses the old method based on the ‘tabl’ real Gestalt selector when launching, so the selector origin (NewGestalt or NewGestaltValue) is then unknown.
If you have a system error when launching GestLab even with Secure Launching feature on, try to throw away the files “GestLab Prefs” and “base+” because they could have been corrupted.
Help balloons
To see help balloons, you can turn this feature on in the Help menu as usual (“Show Balloons”). A more convenient way is provided by GestLab. Press Command and Option keys simultaneously: balloons are available until keys are released.
To-do list (if enough time to implement)
This is not an exhaustive list and there is no level of priority in it:
• Support of scriptability
• Support of remote configs
• Accurate list of mnemonics as found in Gestalt.h universal headers
• Static database should be an external data file and not resources in the app
• A list of selectors displayed hierarchically to provide a less technical look for end users
• …
This point is a permanent quest:
• More exhaustivity in the static database (send your GestLab config at jpc83@calva.net to contribute!)
Known bugs
I am waiting for your reports! But:
• some memory leaks have to be resorbed (it seems it is the CodeWarrior fault, not mine);
• some cosmetic bugs when GestLab is used on pre-8.5 systems with Appearance Manager 1.0.x (they are update problems from Appearance Manager corrected by version 1.1) or when Kaleidoscope is used.
Be careful: app signature changed between b3 and b4. In order to use the same preferences file, give it ‘gLab’ as a new creator (or trash GestLab Prefs file). The same for documents saved from older GestLab versions if you want to open them by using double-click (drag and drop on GestLab icon still works). The same for dynamic database (“base+” file).
To change the creator, drag and drop Finder icons of documents to convert on the “GestLab creator exch” AppleScript provided in this package. Sorry, this modification should have been done more earlier.
Histo
Version 1.0 (24 May 99): Better analysis when searching for selector origin within resources (results implicitely indicate probability for each file to have posted the selector), and selector origin can be searched from any folder (see doc). Selector ‘mnam’ used whereever it is possible. 700 selectors in the static database.
Version 1.0b4 (2 May 99): Now there are subwindows to compare file lists from a Compare window (see doc). Selectors can be selected by type or flags in the static database. Virtual configs are correctly opened even if the local config is collapsed. Other minor bugs corrected. More help balloons. Clever zoom in Compare windows. App signature has changed (it is no longer the same as Gestalt.Appl): see above. 665 selectors in the static database.
Version 1.0b3 (5 Apr 99): Help balloons in windows (press Command and Option keys simultaneously to see them). New picture (JJ Cortes’ courtesy) in the “About GestLab” window. Some minor bugs corrected. 637 selectors in the static database.
Version 1.0b2 (14 Mar 99): No longer crash when using main list pop-up menu after closing a virtual config. A crash could occur when displaying an hexadecimal box with some values returned by the Gestalt selector. You cannot open a new config if memory is too low to allow GestLab to run correctly. Added the pseudo-selector “Config overview”. The static database can be sorted by date. 584 selectors in the static database.
Version 1.0b1 (3 Mar 99): First version made widely available on Internet. 579 selectors in the static database.